﻿Imports System.Xml
''' <summary>
''' 过程部的命令采集
''' </summary>
''' <remarks></remarks>
Public Class clsStatementDefine
#Region "逻辑层次的整理"
    ''' <summary>
    ''' 当前处理的Process
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared CurrentProcessSection As SectionNode
    ''' <summary>
    ''' 当前处理的节点
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared GlobalTargetNode As clsSyntaxNode
    ''' <summary>
    ''' 分析指定行
    ''' </summary>
    ''' <remarks>式样书：语法树生成方法</remarks>
    Public Shared Sub ProcessLines()
        Dim ProcessLineNo As Integer = 1
        GlobalTargetNode = mProcedureNode.MainSection
        CurrentProcessSection = GlobalTargetNode
        Do While ProcessLineNo <= PL1Source.Count
            ProcessLineNo = GetProcedureTree(ProcessLineNo)
        Loop
    End Sub
    ''' <summary>
    ''' 对于语句进行处理
    ''' </summary>
    ''' <param name="CurrentLineNumber">过程开始行号</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetProcedureTree(ByVal CurrentLineNumber As Integer) As Integer
        Dim CurrentText As String = PL1Source(CurrentLineNumber - 1)
        '删除末尾一个分号
        If Mid(CurrentText, CurrentText.Length) = ";" Then CurrentText = Mid(CurrentText, 1, CurrentText.Length - 1)
        '注释处理
        Dim SingleLineWithOutComment As String = CurrentText
        Dim SingleComment As String = String.Empty
        If InStr(CurrentText, "*/") > 0 Then
            SingleLineWithOutComment = ClearComment(SingleLineWithOutComment)
            SingleComment = GetComment(CurrentText)
        End If
        'COMMENT
        If SingleLineWithOutComment.Trim = String.Empty Then
            If mIdentificationNode.ProgramID = String.Empty Then
                Dim CommentItem As XmlElement = mXmlDocument.CreateElement("COMMENTLIST")
                CommentItem.SetAttribute("TEXT", Mid(CurrentText, 2, CurrentText.Length - 2))
                mIdentificationNode.CommentList.Add(CommentItem)
            Else
                GlobalCommentList.Add(Mid(CurrentText, 2, CurrentText.Length - 2))
            End If
            Return CurrentLineNumber + 1
        End If

        'DCL
        If SingleLineWithOutComment.StartsWith("DCL" & Space(1)) Then
            Dim DCLDataNode As List(Of XmlElement) = clsDataDefine.GetDataTree(PL1Source(CurrentLineNumber - 1))
            If mProcedureNode.SectionList.Count = 0 Then
                For Each DataNode As XmlElement In DCLDataNode
                    CurrentProcessSection.AddData(DataNode)
                Next
            End If
            Return CurrentLineNumber + 1
        End If

        Dim NextScan As Integer
        'PROC
        NextScan = IsPROC(CurrentLineNumber, GlobalTargetNode)
        If NextScan > 0 Then
            '主程序的时候，将注释都放在程序头部
            If GlobalTargetNode Is mProcedureNode.MainSection Then GlobalTargetNode.SetCommentList()
            Return NextScan
        End If
        'IF
        NextScan = IsIF(CurrentLineNumber, GlobalTargetNode)
        If NextScan > 0 Then
            Return NextScan
        End If
        'SELECT
        NextScan = IsSELECT(CurrentLineNumber, GlobalTargetNode)
        If NextScan > 0 Then
            Return NextScan
        End If
        'LOOP
        NextScan = IsLoop(CurrentLineNumber, GlobalTargetNode)
        If NextScan > 0 Then
            Return NextScan
        End If

        Dim SingleOprXml As XmlElement = clsStatementControl.GetSingleOpr(PL1Source(CurrentLineNumber - 1).Trim)
        'INCLUDE
        If SingleOprXml.Name = "INCLUDE" Then
            'INCLUDE的特殊处理，如果这个INCLUDE的内容是数据的话，放入当前节点的数据部
            Dim strCopyName As String = SingleOprXml.GetAttribute("COPYBOOKNAME")
            If clsCopyBookList.GetCopyBookInfoByName(strCopyName).IsDisposed Then
                '防止初始化里的废止COPY句
                Return CurrentLineNumber + 1
            End If
            If clsCopyBookList.GetCopyBookInfoByName(strCopyName).CopyBookType = enmCopyBookType.Data Then
                CurrentProcessSection.AddData(SingleOprXml)
            Else
                CType(GlobalTargetNode, SectionNode).AddOperation(SingleOprXml)
            End If
            Return CurrentLineNumber + 1
        End If
        'Section块的动作语句
        Dim secNode As clsStatementBlock = CType(GlobalTargetNode, clsStatementBlock)
        '可能出现问题的地方。一个行注释有可能真的属于一个命令
        If secNode.SingleStatementList.Count = 0 And secNode.CommentList.Count = 0 Then
            For Each SubXmlNode As XmlNode In SingleOprXml.ChildNodes
                If SubXmlNode.Name = "COMMENTLIST" Then
                    '需要确认，把这个节点加到其他地方的话，原来地方会消失是否正确的XML式样
                    secNode.CommentList.Add(SubXmlNode)
                End If
            Next
        End If
        secNode.AddOperation(SingleOprXml)
        Return CurrentLineNumber + 1
    End Function
    ''' <summary>
    ''' 判断是否为一个过程
    ''' </summary>
    ''' <param name="StartLineNumber"></param>
    ''' <param name="TargetNode"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsPROC(ByVal StartLineNumber As Integer, ByVal TargetNode As clsSyntaxNode) As Integer
        Dim CurrentText As String = PL1Source(StartLineNumber - 1)
        '删除末尾一个分号
        If Mid(CurrentText, CurrentText.Length) = ";" Then CurrentText = Mid(CurrentText, 1, CurrentText.Length - 1)
        '注释处理
        Dim SingleLineWithOutComment As String = CurrentText
        Dim SingleComment As String = String.Empty
        If InStr(CurrentText, "*/") > 0 Then
            SingleLineWithOutComment = ClearComment(SingleLineWithOutComment)
        End If
        If InStr(CurrentText, "*/") > 0 Then
            SingleComment = GetComment(CurrentText)
        End If
        Dim strwords As List(Of String) = GetSyntaxToken(SingleLineWithOutComment)

        'SectionName:PROC; 或者 SectionName:PROC(Args); 
        If InStr(SingleLineWithOutComment, ":PROC") > 0 Then
            If SingleLineWithOutComment.EndsWith(":PROC") Then
                Dim CurrentSectionNode As SectionNode = New SectionNode
                CurrentSectionNode.IsTopStatementBlock = True
                CurrentProcessSection = CurrentSectionNode
                CurrentSectionNode.SectionName = Mid(SingleLineWithOutComment, 1, InStr(SingleLineWithOutComment, ":") - 1)
                '如果存在积累下来的成段注释,则将这些注释做为这个项目的注释
                CurrentSectionNode.SetCommentList()
                mProcedureNode.AddSection(CurrentSectionNode)
                Return GetSectionEnd(CurrentSectionNode, StartLineNumber) + 1
            Else
                Dim CurrentSectionNode As SectionNode = New SectionNode
                CurrentSectionNode.IsTopStatementBlock = True
                CurrentProcessSection = CurrentSectionNode
                CurrentSectionNode.SectionName = Mid(SingleLineWithOutComment, 1, InStr(SingleLineWithOutComment, ":") - 1)
                '如果存在积累下来的成段注释,则将这些注释做为这个项目的注释
                CurrentSectionNode.SetCommentList()
                mProcedureNode.AddSection(CurrentSectionNode)
                Return GetSectionEnd(CurrentSectionNode, StartLineNumber) + 1
            End If
            If InStr(SingleLineWithOutComment, "OPTIONS(MAIN)") > 0 Then
                'BKH:PROC OPTIONS(MAIN);
                mIdentificationNode.ProgramID = Mid(SingleLineWithOutComment, 1, InStr(SingleLineWithOutComment, ":") - 1)
                mIdentificationNode.IsMain = True
                CurrentProcessSection = mProcedureNode.MainSection
                CurrentProcessSection.IsTopStatementBlock = True
                Return GetSectionEnd(mProcedureNode.MainSection, StartLineNumber) + 1
            End If
        End If
        '@JRI  PROC 特殊处理 开始
        If SingleLineWithOutComment.StartsWith("#PROC(") Then
            mIdentificationNode.ProgramID = Mid(SingleLineWithOutComment, InStr(SingleLineWithOutComment, "(") + 1, InStr(SingleLineWithOutComment, ",") - InStr(SingleLineWithOutComment, "(") - 1)
            If SingleLineWithOutComment.EndsWith(",SUB)") Then
                mIdentificationNode.IsMain = False
            End If
            If SingleLineWithOutComment.EndsWith(",MAIN)") Then
                mIdentificationNode.IsMain = True
            End If
            CurrentProcessSection = mProcedureNode.MainSection
            CurrentProcessSection.IsTopStatementBlock = True
            Return GetSectionEnd(mProcedureNode.MainSection, StartLineNumber) + 1
        End If
        If SingleLineWithOutComment.StartsWith("#IPROC(") Then
            Dim StrSection As String = Mid(SingleLineWithOutComment, 8, SingleLineWithOutComment.Length - 8)
            Dim sectionArray As String() = StrSection.Split(",")
            'IPROC作为子程序的标志，可能含有调用参数的信息
            Dim CurrentSectionNode As SectionNode = New SectionNode
            CurrentProcessSection = CurrentSectionNode
            CurrentProcessSection.IsTopStatementBlock = True
            If sectionArray.Length = 1 Then
                CurrentSectionNode.SectionName = StrSection
            Else
                CurrentSectionNode.SectionName = sectionArray(0)
                For i As Byte = 1 To sectionArray.Length - 1
                    CurrentSectionNode.ParaList.Add(sectionArray(i))
                Next
            End If
            '如果存在积累下来的成段注释,则将这些注释做为这个项目的注释
            CurrentSectionNode.SetCommentList()
            mProcedureNode.AddSection(CurrentSectionNode)
            Return GetSectionEnd(CurrentSectionNode, StartLineNumber) + 1
        End If
        '@JRI  PROC 特殊处理 完了
    End Function
#End Region
#Region "具体判断"
    ''' <summary>
    ''' 处理一个过程[返回最后行的行号]
    ''' </summary>
    ''' <param name="SecNode"></param>
    ''' <param name="StartLineNumber"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function GetSectionEnd(ByVal SecNode As SectionNode, ByVal StartLineNumber As Integer) As Integer
        Dim ScanPosition As Integer = StartLineNumber + 1
        Dim SingleLineWithOutComment As String
        Do While (ScanPosition <= PL1Source.Count)
            SingleLineWithOutComment = PL1Source(ScanPosition - 1)
            If InStr(SingleLineWithOutComment, "*/") > 0 Then
                SingleLineWithOutComment = ClearComment(SingleLineWithOutComment)
            End If
            If (SingleLineWithOutComment = ("END " & SecNode.SectionName & ";")) Or _
               (SingleLineWithOutComment = ("END " & mIdentificationNode.ProgramID & ";")) Or _
                SingleLineWithOutComment = "END;" Then
                Return ScanPosition
            End If
            '@JRI  PROC 特殊处理 开始
            If PL1Source(ScanPosition - 1) = "#END;" Or PL1Source(ScanPosition - 1) = "#RETURN;" _
               Or PL1Source(ScanPosition - 1) = "#EXIT;" Then
                Return ScanPosition
            End If
            '@JRI  PROC 特殊处理 完了
            GlobalTargetNode = SecNode
            ScanPosition = GetProcedureTree(ScanPosition)
        Loop
    End Function
    ''' <summary>
    ''' 判断是否非IF块
    ''' </summary>
    ''' <param name="StartLineNumber"></param>
    ''' <param name="TargetNode"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsIF(ByVal StartLineNumber As Integer, ByVal TargetNode As clsStatementBlock) As Integer
        Dim CurrentText As String = PL1Source(StartLineNumber - 1)
        '删除末尾一个分号
        If Mid(CurrentText, CurrentText.Length) = ";" Then CurrentText = Mid(CurrentText, 1, CurrentText.Length - 1)
        '注释处理
        Dim SingleLineWithOutComment As String = CurrentText
        Dim SingleComment As String = String.Empty
        If InStr(SingleLineWithOutComment, "*/") > 0 Then
            SingleLineWithOutComment = ClearComment(SingleLineWithOutComment)
        End If
        If InStr(CurrentText, "*/") > 0 Then
            SingleComment = GetComment(CurrentText)
        End If
        Dim strwords As List(Of String) = GetSyntaxToken(SingleLineWithOutComment)

        Dim RtnLineNumber As Integer = StartLineNumber + 1
        If strwords(0) = "IF" Then
            Dim CurrentIFNode = New IFNode
            '将累计下来的注释放入当前项目
            CurrentIFNode.SetCommentList()
            If GetTokenPos("THEN", strwords) > 2 Then
                Dim strCondition As String = String.Empty
                For i As Integer = 1 To GetTokenPos("THEN", strwords) - 2
                    strCondition &= strwords(i) & Space(1)
                Next
                CurrentIFNode.IFCondition = New ConditionNode(strCondition)
                RtnLineNumber = GetIFEnd(CurrentIFNode, StartLineNumber) + 1
                TargetNode.AddIF(CurrentIFNode)
                Return RtnLineNumber
            End If
        End If
    End Function
    ''' <summary>
    ''' 寻找IF的结束位置[返回最后行的行号]
    ''' </summary>
    ''' <param name="CurrentIFNode"></param>
    ''' <param name="StartLineNumber"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function GetIFEnd(ByVal CurrentIFNode As IFNode, ByVal StartLineNumber As Integer) As Integer
        Dim ScanPosition As Integer = StartLineNumber
        Dim SingleLineWithOutComment As String
        SingleLineWithOutComment = PL1Source(ScanPosition - 1)
        If InStr(SingleLineWithOutComment, "*/") > 0 Then
            SingleLineWithOutComment = ClearComment(SingleLineWithOutComment)
        End If
        If SingleLineWithOutComment.EndsWith("DO;") Then
            '向下寻找END；
            ScanPosition = GetEndPostion(CurrentIFNode.TrueOperationList, ScanPosition)
        Else
            'IF <条件> THEN 语句; 类型  没有DO； 单语句
            Dim strTrueOpr As String = String.Empty
            SingleLineWithOutComment = Mid(SingleLineWithOutComment, 1, SingleLineWithOutComment.Length - 1)
            Dim strwords As List(Of String) = GetSyntaxToken(SingleLineWithOutComment)
            If GetTokenPos("THEN", strwords) > 0 Then
                For i As Integer = GetTokenPos("THEN", strwords) To strwords.Count - 1
                    If i = strwords.Count - 1 Then
                        strTrueOpr &= strwords(i)
                    Else
                        strTrueOpr &= strwords(i) & Space(1)
                    End If
                Next
                '如果THEN后的文字不为空
                strTrueOpr = strTrueOpr.Trim()
                If strTrueOpr <> String.Empty Then
                    CurrentIFNode.TrueOperationList.AddOperation(clsStatementControl.GetSingleOpr(strTrueOpr))
                End If
            End If
        End If
        SingleLineWithOutComment = PL1Source(ScanPosition)
        If InStr(SingleLineWithOutComment, "*/") > 0 Then
            SingleLineWithOutComment = ClearComment(SingleLineWithOutComment)
        End If
        'IF <条件> THEN 语句; 类型,检查下一行是否为ELSE，并且ELSE是不是DO；的块
        If SingleLineWithOutComment.StartsWith("ELSE") Then
            If SingleLineWithOutComment.EndsWith("DO;") Then
                Dim FalseNode As New clsStatementBlock
                ScanPosition = GetEndPostion(CurrentIFNode.FalseOperationList, ScanPosition + 1)
            Else
                If Not (SingleLineWithOutComment.Trim = "ELSE;") Then
                    Dim strFlaseOpr As String = String.Empty
                    Dim strwords As List(Of String) = GetSyntaxToken(SingleLineWithOutComment)
                    For i As Integer = GetTokenPos("ELSE", strwords) To strwords.Count - 1
                        strFlaseOpr &= strwords(i) & Space(1)
                    Next
                    '如果ELSE后的文字不为空
                    strFlaseOpr = strFlaseOpr.Trim
                    If strFlaseOpr <> String.Empty Then
                        CurrentIFNode.FalseOperationList.AddOperation(clsStatementControl.GetSingleOpr(strFlaseOpr))
                    End If
                End If
                ScanPosition += 1
            End If
        End If
        Return ScanPosition
    End Function
    ''' <summary>
    ''' 判断是否为一个SELECT[返回最后行的行号]
    ''' </summary>
    ''' <param name="StartLineNumber"></param>
    ''' <param name="TargetNode"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsSELECT(ByVal StartLineNumber As Integer, ByVal TargetNode As clsStatementBlock) As Integer
        Dim CurrentText As String = PL1Source(StartLineNumber - 1)
        '删除末尾一个分号
        If Mid(CurrentText, CurrentText.Length) = ";" Then CurrentText = Mid(CurrentText, 1, CurrentText.Length - 1)
        '注释处理
        Dim SingleLineWithOutComment As String = CurrentText
        Dim SingleComment As String = String.Empty
        If InStr(CurrentText, "*/") > 0 Then
            SingleLineWithOutComment = ClearComment(CurrentText)
        End If
        If InStr(CurrentText, "*/") > 0 Then
            SingleComment = GetComment(CurrentText)
        End If
        Dim strwords As List(Of String) = GetSyntaxToken(SingleLineWithOutComment)

        Dim RtnLineNumber As Integer = StartLineNumber + 1
        If strwords(0).StartsWith("SELECT") Then
            Dim CurrentSelectNode = New SelectNode
            '将累计下来的注释放入当前项目
            CurrentSelectNode.SetCommentList()
            If strwords(0) = "SELECT" And Not (strwords.Count > 1 AndAlso strwords(1).StartsWith("(")) Then
                'IF...ELSE变体,条件写在WHEN里的情况
                CurrentSelectNode.SwitchCondition = String.Empty
            Else
                If strwords.Count = 1 Then
                    CurrentSelectNode.SwitchCondition = Mid(strwords(0), 8, strwords(0).Length - 8)
                Else
                    CurrentSelectNode.SwitchCondition = Mid(strwords(1), 2, strwords(1).Length - 2)
                End If
            End If
            RtnLineNumber = GetSelectEnd(CurrentSelectNode, StartLineNumber + 1) + 1
            TargetNode.AddSelect(CurrentSelectNode)
            Return RtnLineNumber
        End If
    End Function
    ''' <summary>
    ''' 寻找SELECT的结束位置
    ''' </summary>
    ''' <param name="CurrentSELECTNode"></param>
    ''' <param name="StartLineNumber"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function GetSelectEnd(ByVal CurrentSelectNode As SelectNode, ByVal StartLineNumber As Integer) As Integer
        Dim ScanPosition As Integer = StartLineNumber
        Dim SingleLineWithOutComment As String
        SingleLineWithOutComment = PL1Source(ScanPosition - 1)
        If InStr(SingleLineWithOutComment, "*/") > 0 Then
            SingleLineWithOutComment = ClearComment(PL1Source(ScanPosition - 1))
        End If
        Do While SingleLineWithOutComment <> "END;"
            Dim strwords As List(Of String) = GetSyntaxToken(SingleLineWithOutComment)
            Dim SelectCaseNode As New SelectNode.StruCase
            SelectCaseNode.CaseList = New clsStatementBlock
            If SingleLineWithOutComment.StartsWith("WHEN") Then
                If SingleLineWithOutComment.EndsWith("DO;") Then
                    If strwords(0) = "WHEN" Then
                        'WHEN (XXXXX) DO;
                        SelectCaseNode.Condition = New ConditionNode(Mid(strwords(1), 2, strwords(1).Length - 2))
                    Else
                        'WHEN(XXXXX) DO;
                        SelectCaseNode.Condition = New ConditionNode(Mid(strwords(0), 5, strwords(0).Length - 2))
                    End If
                    ScanPosition = GetEndPostion(SelectCaseNode.CaseList, ScanPosition)
                    CurrentSelectNode.AddSwitchItem(SelectCaseNode)
                Else
                    'WHEN 单行的情况
                    Dim OprLine As String = String.Empty
                    If strwords(0) = "WHEN" Then
                        'WHEN (XXXXX) ;
                        Dim strCondition As String = Mid(strwords(1), 2, strwords(1).Length - 2)
                        SelectCaseNode.Condition = New ConditionNode(strCondition)
                        If strwords.Count > 2 Then
                            '考虑到没有语句的情况
                            For i As Byte = 2 To strwords.Count - 1
                                If strwords(i) <> ";" Then OprLine &= strwords(i) & Space(1)
                            Next
                        End If
                    Else
                        'WHEN(XXXXX) ;
                        Dim strCondition As String = Mid(strwords(0), 5, strwords(0).Length - 2)
                        SelectCaseNode.Condition = New ConditionNode(strCondition)
                        If strwords.Count > 1 Then
                            '考虑到没有语句的情况
                            For i As Byte = 1 To strwords.Count - 1
                                If strwords(i) <> ";" Then OprLine &= strwords(i) & Space(1)
                            Next
                        End If
                    End If
                    'WHEN('031') DO I = 1 TO IMFTEN.FLDCNT;                           
                    '  MXHJK(J) = IMFTEN.DATAFLD(I);                      
                    '  J = J + 1;                                         
                    'END;
                    '这种情况需要通过具体文字去检查LOOP条件是否满足
                    If OprLine <> String.Empty Then
                        Dim GetLoopEnd As Integer = IsLoop(ScanPosition, SelectCaseNode.CaseList, OprLine)
                        If GetLoopEnd <> 0 Then
                            ScanPosition = GetLoopEnd
                        Else
                            SelectCaseNode.CaseList.AddOperation(clsStatementControl.GetSingleOpr(OprLine))
                        End If
                    End If
                    CurrentSelectNode.AddSwitchItem(SelectCaseNode)
                End If
            Else
                If SingleLineWithOutComment.StartsWith("OTHERWISE") Or SingleLineWithOutComment.StartsWith("OTHER") Then
                    SelectCaseNode.Condition = New ConditionNode("OTHERWISE")
                    If PL1Source(ScanPosition - 1).EndsWith("DO;") Then
                        'OTHERWISE DO;
                        ScanPosition = GetEndPostion(SelectCaseNode.CaseList, ScanPosition)
                        CurrentSelectNode.AddSwitchItem(SelectCaseNode)
                    Else
                        'OTHERWISE 单行的情况
                        '这种情况出现在两个句子写在一个行里
                        'If strwords.Count = 3 AndAlso strwords(1) = "DO;" AndAlso strwords(2) = "END;" Then
                        '    'OTHERWISE DO; END: 
                        'Else
                        If strwords.Count = 1 AndAlso (strwords(0) = "OTHERWISE;" Or strwords(0) = "OTHER;") Then
                            '只有 OTHERWISE; 或者 OTHER:
                        Else
                            Dim OprLine As String = String.Empty
                            For i As Byte = 1 To strwords.Count - 1
                                OprLine &= strwords(i) & Space(1)
                            Next
                            SelectCaseNode.CaseList.AddOperation(clsStatementControl.GetSingleOpr(OprLine))
                            CurrentSelectNode.AddSwitchItem(SelectCaseNode)
                        End If
                        'End If
                    End If
                End If
            End If
            ScanPosition = ScanPosition + 1
            SingleLineWithOutComment = PL1Source(ScanPosition - 1)
            If InStr(SingleLineWithOutComment, "*/") > 0 Then
                SingleLineWithOutComment = Mid(SingleLineWithOutComment, InStr(SingleLineWithOutComment, "*/") + 2)
            End If
        Loop
        Return ScanPosition
    End Function
    ''' <summary>
    ''' 判断是否为一个循环
    ''' </summary>
    ''' <param name="StartLineNumber">开始行号</param>
    ''' <param name="TargetNode">填充节点</param>
    ''' <param name="strTestLine">通过具体文本来判断[例如在 WHEN 后面的 DO I = 1 TO X 的情况]</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsLoop(ByVal StartLineNumber As Integer, ByVal TargetNode As clsStatementBlock, Optional ByVal strTestLine As String = "") As Integer
        Dim CurrentText As String = PL1Source(StartLineNumber - 1)
        '删除末尾一个分号
        If Mid(CurrentText, CurrentText.Length) = ";" Then CurrentText = Mid(CurrentText, 1, CurrentText.Length - 1)
        '注释处理
        If strTestLine <> String.Empty Then CurrentText = strTestLine
        Dim SingleLineWithOutComment As String = CurrentText
        Dim SingleComment As String = String.Empty
        If InStr(SingleLineWithOutComment, "*/") > 0 Then
            SingleLineWithOutComment = ClearComment(SingleLineWithOutComment)
        End If
        If InStr(CurrentText, "*/") > 0 Then
            SingleComment = GetComment(CurrentText)
        End If
        Dim strwords As List(Of String) = GetSyntaxToken(SingleLineWithOutComment)

        Dim RtnLineNumber As Integer = StartLineNumber + 1
        Dim HasLabel As Boolean = False
        Dim LabelName As String = String.Empty
        '\XX:DO #XX:DO
        If (strwords(0).StartsWith("\") Or strwords(0).StartsWith("#")) And strwords(0).EndsWith(":DO") Then
            HasLabel = True
            LabelName = Mid(strwords(0), 2, strwords(0).Length - 4)
            strwords(0) = "DO"
        End If
        If strwords(0) = "DO" AndAlso (HasTokenStartWith("WHILE", strwords) Or HasTOKEN("TO", strwords) Or HasTOKEN("UNTIL", strwords)) Then
            Dim CurrentLoopNode = New LoopNode
            '将累计下来的注释放入当前项目
            CurrentLoopNode.SetCommentList()
            If HasLabel Then
                CurrentLoopNode.LabelName = LabelName
            End If
            If HasTOKEN("TO", strwords) Then
                Dim ToPos As Integer = GetTokenPos("TO", strwords)
                CurrentLoopNode.LoopVarName = strwords(ToPos - 4)
                CurrentLoopNode.LoopFrom = strwords(ToPos - 2)
                CurrentLoopNode.LoopTo = strwords(ToPos)
                CurrentLoopNode.LoopBy = 1
                If HasTOKEN("BY", strwords) Then
                    Dim BYPos As Integer = GetTokenPos("BY", strwords)
                    CurrentLoopNode.LoopBy = strwords(BYPos)
                    If CurrentLoopNode.LoopBy = "-" Then
                        CurrentLoopNode.LoopBy &= strwords(BYPos + 1)
                    End If
                End If
            End If
            'WHILE条件的提取
            If HasTOKEN("WHILE", strwords) Then
                Dim ToPos As Integer = GetTokenPos("WHILE", strwords)
                CurrentLoopNode.WhileCondition = New ConditionNode(strwords(ToPos))
            End If
            If HasTokenStartWith("WHILE(", strwords) Then
                Dim ToPos As Integer = GetTokenPos("WHILE", strwords)
                Dim strWHILE As String = String.Empty
                For mIndex As Integer = 0 To strwords.Count - 1
                    If strwords(mIndex).StartsWith("WHILE(") Then
                        strWHILE = strwords(mIndex)
                        Exit For
                    End If
                Next
                strWHILE = Mid(strWHILE, 7, strWHILE.Length - 7).Trim
                CurrentLoopNode.WhileCondition = New ConditionNode(strWHILE)
            End If
            'UNTIL条件的提取
            If HasTOKEN("UNTIL", strwords) Then
                Dim ToPos As Integer = GetTokenPos("UNTIL", strwords)
                CurrentLoopNode.UntilCondition = New ConditionNode(strwords(ToPos))
            End If
            If HasTokenStartWith("UNTIL(", strwords) Then
                Dim ToPos As Integer = GetTokenPos("UNTIL", strwords)
                Dim strUNTIL As String = String.Empty
                For mIndex As Integer = 0 To strwords.Count - 1
                    If strwords(mIndex).StartsWith("UNTIL(") Then
                        strUNTIL = strwords(mIndex)
                        Exit For
                    End If
                Next
                strUNTIL = Mid(strUNTIL, 7, strUNTIL.Length - 7).Trim
                CurrentLoopNode.UntilCondition = New ConditionNode(strUNTIL)
            End If

            RtnLineNumber = GetEndPostion(CurrentLoopNode.LoopList, StartLineNumber)
            TargetNode.AddLoop(CurrentLoopNode)
            Return RtnLineNumber + 1
        End If
    End Function
    ''' <summary>
    ''' 寻找一个DO块的结束位置[返回最后行的行号]
    ''' </summary>
    ''' <param name="CurrentDONode"></param>
    ''' <param name="StartLineNumber"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function GetEndPostion(ByVal CurrentDoNode As clsStatementBlock, ByVal StartLineNumber As Integer) As Integer
        Dim ScanPosition As Integer = StartLineNumber + 1
        Dim SingleLineWithOutComment As String
        SingleLineWithOutComment = PL1Source(ScanPosition - 1)
        If InStr(SingleLineWithOutComment, "*/") > 0 Then
            SingleLineWithOutComment = Mid(SingleLineWithOutComment, InStr(SingleLineWithOutComment, "*/") + 2)
        End If
        Do While (ScanPosition < PL1Source.Count - 1)
            If SingleLineWithOutComment = "END;" Then
                Return ScanPosition
            Else
                GlobalTargetNode = CurrentDoNode
                ScanPosition = GetProcedureTree(ScanPosition)
            End If
            SingleLineWithOutComment = PL1Source(ScanPosition - 1)
            If InStr(SingleLineWithOutComment, "*/") > 0 Then
                SingleLineWithOutComment = Mid(SingleLineWithOutComment, InStr(SingleLineWithOutComment, "*/") + 2)
            End If
        Loop
    End Function
#End Region
End Class
